package com.tomtop.core.datasource.core;

import java.util.Properties;

import org.apache.ibatis.logging.log4j.Log4jImpl;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.ExecutorType;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.ClassUtils;

import com.github.pagehelper.PageHelper;
import com.tomtop.core._enum.CustomStatus;
import com.tomtop.core.datasource.config.DruidConfig.DruidNode;
import com.tomtop.core.datasource.config.DruidProperties;
import com.tomtop.core.datasource.core.AbstractDataBase.Mapper;
import com.tomtop.core.datasource.core.AbstractDataBase.Order;
import com.tomtop.core.exception.CustomException;

import tk.mybatis.spring.mapper.MapperScannerConfigurer;

public class AbstractDataBaseBean {

	public final  AbstractBeanDefinition createDataSource(DruidNode druidNodeConfig,DruidProperties defaultConfig ,String dataSourceName) {
		if(druidNodeConfig==null){
			throw new CustomException(CustomStatus.FAIL,String.format("DynamicDataSource 未初始化 ,dataSourceName=%s,失败原因: 配置参数为空,你的配置可能存在问题!", dataSourceName+""));
		}
		BeanDefinitionBuilder definitionBuilder= BeanDefinitionBuilder.genericBeanDefinition(DynamicDataSource.class);
		definitionBuilder.addConstructorArgValue(druidNodeConfig);
		definitionBuilder.addConstructorArgValue(defaultConfig);
		AbstractBeanDefinition beanDefinition =definitionBuilder.getRawBeanDefinition();
		beanDefinition.validate();
//		try {
//			DynamicDataSource dataSource = DynamicDataSource.create(druidNodeConfig, defaultConfig);
//			beanDefinition.setSource(dataSource);
//		} catch (SQLException e) {
//			throw new CustomException(CustomStatus.FAIL,e,String.format("DynamicDataSource 未初始化 ,dataSourceName=%s,失败原因: 配置参数为空,你的配置可能存在问题!", dataSourceName+""));
//		}
		return beanDefinition; 
	}
	
	public final  AbstractBeanDefinition createTransactionManager(String dataSourceName) {
		BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(DataSourceTransactionManager.class);
		bdb.addConstructorArgReference(dataSourceName);
		return bdb.getRawBeanDefinition(); 
	}
	
	public final  AbstractBeanDefinition createJdbcTemplate(String dataSourceName) {
		BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(JdbcTemplate.class);
		bdb.addConstructorArgReference(dataSourceName);
		return bdb.getRawBeanDefinition(); 
	}
	
	public final AbstractBeanDefinition createSqlSessionFactoryBean(String dataSourceName,String mapperPackage) {
		org.apache.ibatis.session.Configuration configuration=new org.apache.ibatis.session.Configuration();
		configuration.setCacheEnabled(true);
		configuration.setLazyLoadingEnabled(true);
		configuration.setAggressiveLazyLoading(true);
		configuration.setDefaultExecutorType( ExecutorType.SIMPLE);
		configuration.setLogImpl(Log4jImpl.class);
		PageHelper pageHelper=new PageHelper();
		Properties p=new Properties();
		pageHelper.setProperties(p);
		BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(SqlSessionFactoryBean.class);
		bdb.addPropertyValue("configuration", configuration);
		bdb.addPropertyValue("failFast", true);
		bdb.addPropertyReference("dataSource", dataSourceName);
		bdb.addPropertyValue("plugins", new Interceptor[]{pageHelper});
		String mapperPackagePath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+ ClassUtils.convertClassNameToResourcePath(new StandardEnvironment().resolveRequiredPlaceholders(mapperPackage)) + "/*.xml";
		try {
			bdb.addPropertyValue("mapperLocations", new PathMatchingResourcePatternResolver().getResources(mapperPackagePath));
		} catch (Exception e) {
			throw new CustomException(CustomStatus.FAIL,e,String.format("SqlSessionFactory 初始化失败  mapperPackage=%s",mapperPackage+""));
		}
		return bdb.getBeanDefinition();
	}	

	public final AbstractBeanDefinition createScannerConfigurerBean(String sqlSessionFactoryName,String basepackage,Mapper mappers,Order order){
		BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
		Properties properties=new Properties();
		properties.setProperty("notEmpty", "true");
		properties.setProperty("ORDER",  order!=null ?order.order:Order.BEFORE.order);
		properties.setProperty("mappers",mappers!=null?mappers.mapper: Mapper.DEFAULT.mapper);
		bdb.addPropertyValue("properties", properties);
		bdb.addPropertyValue("sqlSessionFactoryBeanName", sqlSessionFactoryName);
		bdb.addPropertyValue("basePackage", basepackage);
		return bdb.getRawBeanDefinition();
	}
}
